MDEV-40383:innodb_gis.point_basic fails on replay - #5446
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
d7ceeb9 to
12df834
Compare
|
Test failure is fixed with the changes |
| if (require_quote && pref_str_in_hex && tmp.length()) | ||
| { | ||
| output.append(STRING_WITH_LEN("0x")); | ||
| output.append_hex(tmp.ptr(), tmp.length()); |
There was a problem hiding this comment.
you know the charset of tmp and charset of output. You must always use hex if tmp cannot be converted to output charset without losses. Otherwise you don't need hex. It's not an external property that you need to pass as an argument.
There was a problem hiding this comment.
May be I should narrow down the scope of change. For Geometry types I can use HEX, and for others, existing string representation should work, as it was already taken care to use charsets.
There was a problem hiding this comment.
No! This is the whole point. Geometry is just a special case of a binary string that cannot necessarily be converted to the target charset. It is not a property of a type, it's a property of the charset. You must use hex in all cases where you cannot perform a lossless conversion from the source to the target charset.
There was a problem hiding this comment.
updated it now.
| join_read_system()/join_read_const() only fetch the columns present in | ||
| table->read_set. That's sufficient for execution, but when we record the | ||
| const row for replay it yields an incomplete REPLACE INTO -- columns that | ||
| are NOT NULL and have no default then depend on a relaxed sql_mode (see |
There was a problem hiding this comment.
just make sure all columns always have defaults and you won't need any of the below!
There was a problem hiding this comment.
@vuvova , do you suggest generating default values for any possible column type? How feasible is this given that there may be something fancy like GEOMETRY?
| { | ||
| Field *field= *pfield; | ||
| /* Generated columns cannot be assigned a value in REPLACE INTO */ | ||
| if (field->vcol_info) |
There was a problem hiding this comment.
This function is also used by dbug_format_row() / dbug_print_row(), so this brings in a regression for those (same applies below too)
There was a problem hiding this comment.
Agree. However, I believe dbug_format_row() / dbug_print_row() are only used when debug is enabled. Since it is low risk method, we clubbed our changes with this. How, about if we always set print_names=true?
There was a problem hiding this comment.
At least, I'd suggest adding an argument like print_virtual_cols to format_and_store_row(), otherwise silently dropping vcols looks unexpected
There was a problem hiding this comment.
if we always set print_names=true
Yes, this looks more robust than positional printing
12df834 to
4ebbfec
Compare
9f50d3c to
cf67fb5
Compare
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
cf67fb5 to
d817206
Compare
| return length; | ||
| } | ||
|
|
||
| static bool is_target_cs_superset(CHARSET_INFO *from_cs, CHARSET_INFO *to_cs) |
There was a problem hiding this comment.
This name is not descriptive, consider renaming to something like:
- charset_conversion_is_lossless
- can_convert_losslessly
Or even invert it and rename to charset_conversion_may_lose_data, so that the code on the call site becomes more readable:
if (require_quote && tmp.length() &&
charset_conversion_may_lose_data(field->charset(), output.charset()))
There was a problem hiding this comment.
Please, make sure @abarkov reviews it. And may be we already have a method to do it, no need to invent a new one
There was a problem hiding this comment.
Sure, tried using the function can_be_safely_converted_to() defined in sql_string.h. But, it doesn't work correctly.
d817206 to
b4d06f3
Compare
There are 2 problems: - 1. The REPLACE statement that is recorded doesn't store the value of geometry type field correctly. 2. The table definition that got recorded has fields with non-null constraint, and no default value is specified. Also, the "REPLACE INTO" statement that gets stored in the context, doesn't have any value specified for these non-null fields. Solution is to: - 1. When using REPLACE INTO statement, store all the non-numeric values in HEX, whenever conversion from field's charset to output's charset is lossy. 2. Instead of storing only the column values that were projected in the query, store all the non-virtual column values into the recorded REPLACE INTO statement. Implementation details: - 1. Introduce a new method is_charset_conversion_lossless() in filesort.cc, to check if the output charset to which field's data is being written to, results in a lossless conversion. If so, non-numeric values being witten using REPLACE INTO statement are stored in string representation, else they are converted to HEX. 2. From join_read_const(), and join_read_system() methods in sql_select.cc, re-read the const row for all the non-virtual fields in the table. After the row is re-read and recorded, restore the table->read_set, table->status, and the const row, to the value that was before.
b4d06f3 to
46c4a5e
Compare
There are 2 problems: -
value of geometry type field correctly.
and no default value is specified.
Also, the "REPLACE INTO" statement that gets stored in the context,
doesn't have any value specified for these non-null fields.
Solution is to: -
whenever conversion from field's charset to output's charset is lossy.
query, store all the non-virtual column values into the recorded
REPLACE INTO statement.
Implementation details: -
to check if the output charset to which field's data is being written to,
results in a lossless conversion. If so, non-numeric values being witten
using REPLACE INTO statement are stored in string representation,
else they are converted to HEX.
re-read the const row for all the non-virtual fields in the table.
After the row is re-read and recorded, restore the table->read_set,
table->status, and the const row, to the value that was before.